#ifndef __GWMD5_H__
#define __GWMD5_H__

#include <stdio.h>
#include <string>
#include <string.h>

/**
*@file       gwmd5.h
*@brief      md5 sum
*
*@author     graywind
*@version    1.0.0.0
*@data       2011/12/27
*/

///util stuff
namespace gwBedrockUtil
{
        ///generate md5 sum
        class gwMD5Transformer;
}

namespace gwBedrockUtil
{
        ///generate md5 sum
        class gwMD5Transformer
        {
        private:
                ///md5 context
                struct gwMD5Context
                {
                        unsigned int  buf[4];
                        unsigned int  bits[2];
                        unsigned char in[64];
                };

        private:
                ///@brief    start MD5 accumulation
                ///param[in] context   gwMD5Context object's pointer
                ///retval    void
                static void init_context(gwMD5Context* context);
                ///@brief    update context to reflect the concatenation of another buffer full of bytes
                ///param[in] context     gwMD5Context object's pointer
                ///param[in] content_in  array in bytes for cal
                ///param[in] length_in   bytes length of incoming array
                ///retval    void
                static void update_context(gwMD5Context* context, const unsigned char* content_in, unsigned length_in);
                ///@brief    pad to 64-byte boundary with the bit pattern
                ///param[in] context gwMD5Context object's pointer
                ///param[in] dig     16 bytes array
                ///retval    void
                static void pad_context(gwMD5Context* context, unsigned char dig[16]);
                ///@brief    this code is harmless on little-endian machines
                ///param[in] buf    incoming data to process with
                ///param[in] length bytes length
                ///retval
                static void bytes_reserve(unsigned char* buf, unsigned length);
                ///@brief    core of the MD5 algorithm
                ///param[in] buf   context chaining variables
                ///param[in] in    md5 buffer
                ///retval    void
                static void transform(unsigned int buf[4], const unsigned int in[16]);

        public:
                ///@brief    transform to md5 string
                ///param[in] in     incoming string
                ///retval    std::string     md5 sum
                static std::string generate(const std::string& in);
        };
}


#endif
